package com.hubu.admin.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.*;

//视频教程：https://www.bilibili.com/video/BV1mm4y1X7Hc?p=18&spm_id_from=pageDriver&vd_source=4c11ab176d75ad5cbf02e8ed840601ed
//工具类：https://blog.csdn.net/qq_57147093/article/details/127650933
@Component
public class JwtUtils {

    /**
     * JWT_TTL 在这里设置的是时间 1000ms = 1s;则 60 * 1000*3L 这里为三十分钟。
     */
    public static final long JWT_TTL = 60 * 1000 * 300L;
    public static final String JWT_KEY = "u2ui";

    /**
     * uuid 生成对随机数 作为id
     * @return
     */
    public static String getUUID() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }

    /**
     * 创建jwt构建器的方法
     * @param subject
     * @param ttlMillis
     * @param uuid
     * @return
     */
    private JwtBuilder getJwtBuilder(String subject, Long ttlMillis, String uuid) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        //生成密钥
        SecretKey secretKey = generaKey();
        long nowMillis = System.currentTimeMillis();
        //生成系统当前时间
        Date now = new Date(nowMillis);
        //如果没有有效期，测采用默认有效期
        if (ttlMillis == null) {
            ttlMillis = JWT_TTL;
        }
        //生成到期时间
        long expMillis = nowMillis + ttlMillis;
        Date expDate = new Date(expMillis);
        return Jwts.builder()
                .setId(uuid) //随机数id
                .setSubject(subject)//载荷（对象）
                .setIssuer("sg")//作者
                .setIssuedAt(now)//系统当前时间
                .signWith(signatureAlgorithm, secretKey)//加密
                .setExpiration(expDate);//有效期绝对时间

    }

    /**
     * 生成默认有效期的token
     * @param subject
     * @return
     */
    public String createJWT(String subject) {
        return getJwtBuilder(subject, null, getUUID()).compact();
    }

    /**
     * 生成指定有效期的token
     * @param subject
     * @param ttlMillis
     * @return
     */
    public String createJWT(String subject, Long ttlMillis) {
        return getJwtBuilder(subject, ttlMillis, getUUID()).compact();
    }

    public String createJWT(String id, String subject, Long ttlMillis) {
        return getJwtBuilder(subject, ttlMillis, id).compact();
    }

    /**
     * 生成加密的密匙
     * @return
     */
    private static SecretKey generaKey() {
        byte[] encodedKey = Base64.getDecoder().decode(JWT_KEY);
        SecretKey key=new SecretKeySpec(encodedKey,0,encodedKey.length,"AES");
        return key;
    }

    /**
     * 解析token
     * @param token
     * @return
     */
    public Claims parseJWT(String token) {
        SecretKey key = generaKey();
        return Jwts.parser()
                .setSigningKey(key)
                .parseClaimsJws(token)
                .getBody();
    }
}
